import HashMap from '@ohos.util.HashMap';
import utils from '@ohos/axios/src/main/ets/components/lib/utils';
import { HttpMethod } from './HttpConstants';
import { HttpDecorator } from './HttpDecorators';
import { Utils } from './Utils';

export class Request {
  constructor(
    public baseUrl: string,
    public url: string,
    public httpMethod: HttpMethod,
    public headers: HashMap<string, string>,
    public queryParams: HashMap<string, string>,
    public body: object | null
  ) {
  }
}

export namespace Request {
  export class Builder {
    private url: string = undefined
    private baseUrl: string = undefined
    private httpMethod: HttpMethod = undefined
    private headers: HashMap<string, string>
    private queryParams: HashMap<string, string>
    private body: object

    constructor(private httpDecorator?: HttpDecorator) {
      this.headers = new HashMap<string, string>()
      this.queryParams = new HashMap<string, string>()
    }

    setHttpMethod(httpMethod: HttpMethod): Builder {
      this.httpMethod = httpMethod
      return this
    }

    setUrl(url: string): Builder {
      this.url = url
      return this
    }

    setBody(body: any): Builder {
      this.body = body
      return this
    }

    setBaseUrl(baseUrl: string): Builder {
      this.baseUrl = baseUrl
      return this
    }

    getUrl(): string {
      return this.url
    }

    addHeader(name: string, value: string): Builder {
      this.headers.set(name, value)
      return this
    }

    addHeaders(headers: HashMap<string, string>): Builder {
      this.headers.setAll(headers)
      return this
    }

    addQueryParams(queryParams: HashMap<string, string>): Builder {
      this.queryParams.setAll(queryParams)
      return this
    }

    build(): Request {
      if (this.httpDecorator) {
        this.applyDefaultRequest()
      }
      return new Request(this.baseUrl, this.url, this.httpMethod, this.headers, this.queryParams, this.body)
    }

    private applyDefaultRequest() {
      const request = this.httpDecorator.axios.defaults
      if (Utils.isUndefined(this.httpMethod)) {
        this.httpMethod = HttpMethod.create(request.method)
      }
      if (Utils.isEmpty(this.url)) {
        this.url = request?.url
      }
      if (Utils.isEmpty(this.baseUrl)) {
        this.baseUrl = request?.baseURL
      }
      if (request?.headers) {
        const headers = request?.headers && utils.merge(
          request?.headers.common,
          request?.headers[request.method]
        );
        Object.entries(headers).forEach(([k, v]) => {
          this.headers.set(k, v + "");
        });
      }
    }
  }
}